/*PAC UTILS*/


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "pvrheader.h"








int extract(char *file){

	FILE *fp,*fnew;
	int datasize;
	char *img,*buffer;
	pvr_hdr hdr;
	char filename[30];
	char dir[100];
	char temp[100];
	char output[100];
	int count=0;
	int i=0;
	uint32 ver;
	char *head,*prev;
	


	strcpy(filename,file);

	/*asignamos valores al header*/
	hdr.gbix=0x58494247; //GBIX alreves
	hdr.length=0x00008;
	hdr.index1=0x04;
	hdr.index2=0x00;
	hdr.pvrt= 0x54525650;//PVRT alreves
	//hdr.filelength=offset;//0x4810;


;

	/*open file*/
	fp = fopen(filename, "rb");
	if (fp == NULL) {
		fprintf(stderr, "ERROR:File %s not found\n",filename);
		return 0;
	}

	sscanf(filename,"%[^.]",temp);
	printf("creating folder %s\n",temp);
	mkdir(temp);
	chmod(temp,0777);

	getcwd(&dir,100);

	strcat(dir,"/");
	strcat(dir,temp);
	

	img=malloc(32768);
	buffer=malloc(4);
	head=malloc(4);
	prev=malloc(4);

	memset(img,0,32768);
	memset(buffer,0,4);
	memset(prev,0,4);
	memcpy(prev,buffer,4);
	/*read header, 8 bytes*/
	fread( head, 4, 1, fp );
	//fseek ( fp, -4, SEEK_CUR );

	

	for(;;){
		//strcpy(filename,"");
		
		/*create file*/
		if(count==0){
			count=4;
			printf("creating new file\n");
			sprintf(output,"%s/imagen%d.pvr",dir,i);
			fnew = fopen(output, "wb");
			if (fnew == NULL) {
			fprintf(stderr, "ERROR:Cannot create file\n");
			return 0;
			}

			/*read texture attributes from header*/
			
			fread( img, 4, 1, fp );
			memcpy(&hdr.type,img,4);

			fread( img, 2, 1, fp );
			memcpy(&hdr.width,img,2);
			fread( img, 2, 1, fp );
			memcpy(&hdr.height,img,2);
	
			/*skip header, 8 bytes*/
			fseek ( fp, 12, SEEK_CUR );

			
			

			//count=0;

		}

			/*write data into buffer*/
			//fread( buffer, 8, 1, fp );
			//memcpy(img,buffer,4);
			memcpy(prev,buffer,4);
			fread( buffer, 4, 1, fp );
			if(feof(fp)) break;
			memcpy(img+count,buffer,4);
			//imgcount=*buffer;
			//printf("count: %d\n",count);
			count+=4;
			ver=*prev;
		
		/*end of block*/
		if((memcmp(head,buffer,4)==0)&&(!ver)){
			fseek ( fp, 8, SEEK_CUR );
			fread( buffer, 4, 1, fp );
			fseek ( fp, -12, SEEK_CUR );
			ver=1;
			ver=*buffer^0xFFFFFFEB;
			printf("%x\n",*buffer);
			if(ver==0xFFFFFFFF){ 
				printf("writing file %s, size %d\n",output,count-4);
				hdr.filelength=count;
				fwrite(&hdr, sizeof(hdr), 1, fnew);

				/*write data into file*/
				fwrite(img, count-4, 1, fnew);
			
				fclose(fnew);
				memset(img,0,32768);
				count=0;
				i++;
				//fseek ( fp, -12, SEEK_CUR );
			}
			
		}
		
		
		//fseek ( fp, 20480, SEEK_CUR );		
	}

			if(fnew){
				printf("writing file %s, size %d\n",output,count-4);
				hdr.filelength=count;
				fwrite(&hdr, sizeof(hdr), 1, fnew);

				/*write data into file*/
				fwrite(img, count, 1, fnew);
			
				fclose(fnew);
			}


	fclose(fp);

}


/*dirrrrrrrrrrrrty 
detect file size
haha, it works  */
int detect(char* file,int position){


	FILE *fp;
	char *hdr,*tmp;
	int size=4;
	
	

	fp = fopen(file, "rb");
	if (fp == NULL) {
		fprintf(stderr, "ERROR:File %s not found\n",file);
		return 0;
	}

	hdr=malloc(4);
	tmp=malloc(4);

	fseek ( fp, position, 0 );

	fread( hdr, 4, 1, fp );
	//fread( tmp, 12, 1, fp );
	
	

	while(fread( tmp, 4, 1, fp )==1){
		if(strcmp(hdr,tmp)==0) break;
		size+=4;
	}

	fclose(fp);

return size;
	

	

}


/*++++++ENCODE FILES+++++++*/
int encode(char* file){

	FILE *fp,*ftex,*fout;
	int size;
	char *img,*buffer;
	char filename[30];
	char dir[100];
	char temp[100];
	char output[100];
	int count=0;
	int i=0;
	uint32 ver;
	char *head,*prev,*header;
	


	strcpy(filename,file);

	


;

	/*open file*/
	fp = fopen(filename, "rb");
	if (fp == NULL) {
		fprintf(stderr, "ERROR:File %s not found\n",filename);
		return 0;
	}
	


	sscanf(filename,"%[^.]",temp);
	printf("using directory %s\n",temp);
	sprintf(filename,"new%s",file);
	printf("creating file %s\n",filename);

	/*create output file*/
	fout = fopen(filename, "wb");
	if (fp == NULL) {
		fprintf(stderr, "ERROR:Cannot create file %s\n",filename);
		return 0;
	}
	//mkdir(temp);
	//chmod(temp,0777);

	getcwd(&dir,100);

	strcat(dir,"/");
	strcat(dir,temp);
	

	img=malloc(32768);
	header=malloc(24);
	buffer=malloc(4);
	head=malloc(4);
	prev=malloc(4);

	memset(img,0,32768);
	memset(buffer,0,4);
	memset(prev,0,4);
	memcpy(prev,buffer,4);
	/*read header, 8 bytes*/
	fread( head, 4, 1, fp );
	fseek ( fp, -4, SEEK_CUR );

	

	
	for(;;){
				
		/*end of block*/
		if((memcmp(head,buffer,4)==0)&&(!ver)){
			fseek ( fp, 8, SEEK_CUR );
			fread( buffer, 4, 1, fp );
			fseek ( fp, -12, SEEK_CUR );
			ver=1;
			ver=*buffer^0xFFFFFFEB;
			printf("%x\n",*buffer);
			if(ver==0xFFFFFFFF){ 	//header found!
			
				fseek ( fp, -4, SEEK_CUR );
				fread( header, 24, 1, fp );
				sprintf(output,"%s/imagen%d.pvr",dir,i);
				printf("openning file %s\n",output);
				ftex = fopen(output, "rb");
				if (ftex == NULL) {
					fprintf(stderr, "ERROR:Cannot open file %s\n",output);
					return 0;
				}

				fseek(ftex, 0, SEEK_END); // seek to end of file
				size = ftell(ftex); // get current file pointer
				fseek(ftex, 0, SEEK_SET); // seek back to beginning of file

				
				
				fseek ( ftex, 36, SEEK_CUR ); //skip pvr header
				fread( img, size-36, 1, ftex ); //read entire texture
							
				
				if (size==18464) size=20492; //fix export of pvr export


				fread( buffer, 4, 1, fp );
				printf("writing file %s, size %d\n",output,size);

				/*write header into file*/				
				//hdr.filelength=count;
				fwrite(header, 24, 1, fout);

				/*write data into file*/
				fwrite(img, size-36, 1, fout);
			
				fclose(ftex);
				memset(img,0,32768);

				i++;
				//fseek ( fp, -12, SEEK_CUR );
			}
			
		}

			memcpy(prev,buffer,4);
			ver=*prev;
			fread( buffer, 4, 1, fp );
			if(feof(fp)) break;
		
		
				
	}

			/*if(ftex){
				printf("writing file %s, size %d\n",output,size);
				//hdr.filelength=count;
				//fwrite(header, 20, 1, fout);

				
				fwrite(img, size, 1, fout);
			
				fclose(fout);
			}*/


	fclose(fp);


}

int main(int argc, char *argv[]) {

	

	if (argc != 3) {
		printf("pac files decoder/encoder\nusage: pacutils option filename\noptions:\n  -x extract\n  -e encode\n");
		return 0;
	}



	if (!strcmp(argv[1],"x")) {
			
		extract(argv[2]);

	}else if (!strcmp(argv[1],"e")) {
		encode(argv[2]);

	}


	

return 0;
	


}

